package com.project.common.domain.datascope;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.stp.StpUtil;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.Session;
import org.springframework.stereotype.Component;


/**
 * 数据权限控制
 */
@Aspect
@Component
public class DataScopeDataAspect {

    @PersistenceContext
    private EntityManager entityManager;

    @Pointcut("@annotation(com.project.common.domain.datascope.DataScope)")
    public void dataScopePointCut() {
    }

    @Around("dataScopePointCut()")
    public Object doProcess(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            if (!StpUtil.isLogin()) {
                return joinPoint.proceed();
            } else {
                Long createBy = StpUtil.getLoginIdAsLong();
                String scope = (String) StpUtil.getExtra("sysScope");
                String orgKey = (String) StpUtil.getExtra("orgKey");
                String roleKeys = (String) StpUtil.getExtra("roleKeys");
                // 来源，admin-管理端 app-APP端 wx-小程序 h5-手机WEB
                String source = (String) StpUtil.getExtra("source");
                SaRequest request = SaHolder.getRequest();//请求头添加了gsource
                // System.out.println(request.getHeader("source"));
                if(!"admin".equals(source) || "web".equals(request.getHeader("source"))){
                    return joinPoint.proceed();
                }
                Session session = entityManager.unwrap(Session.class);
                //数据范围（0-本人，1-下级岗位，2-本组织，3-所有）
                if(scope == null){
                    scope = "1";
                }
                if ("0".equals(scope) && null != createBy) {
                    session.enableFilter("createByFilter").setParameter("createBy", createBy);
                }
                if ("2".equals(scope) && StringUtils.isNotBlank(orgKey)) {
                    session.enableFilter("orgKeyFilter").setParameter("orgKey", orgKey + "%");
                }
                if ("1".equals(scope) && StringUtils.isNotBlank(roleKeys)) {
                    if (!roleKeys.contains(",")) {
                        session.enableFilter("roleKeysFilter").setParameter("roleKeys", "%" + roleKeys + "%");
                    } else {
                        String[] split = roleKeys.split(",");
                        if (split.length == 2) {
                            session.enableFilter("roleKeysFilter2")
                                    .setParameter("roleKeys1", "%" + split[0] + "%")
                                    .setParameter("roleKeys2", "%" + split[1] + "%");
                        }
                        if (split.length == 3) {
                            session.enableFilter("roleKeysFilter3")
                                    .setParameter("roleKeys1", "%" + split[0] + "%")
                                    .setParameter("roleKeys2", "%" + split[1] + "%")
                                    .setParameter("roleKeys3", "%" + split[2] + "%");
                        }
                        if (split.length == 4) {
                            session.enableFilter("roleKeysFilter4")
                                    .setParameter("roleKeys1", "%" + split[0] + "%")
                                    .setParameter("roleKeys2", "%" + split[1] + "%")
                                    .setParameter("roleKeys3", "%" + split[2] + "%")
                                    .setParameter("roleKeys4", "%" + split[3] + "%");
                        }
                        if (split.length == 5) {
                            session.enableFilter("roleKeysFilter5")
                                    .setParameter("roleKeys1", "%" + split[0] + "%")
                                    .setParameter("roleKeys2", "%" + split[1] + "%")
                                    .setParameter("roleKeys3", "%" + split[2] + "%")
                                    .setParameter("roleKeys4", "%" + split[3] + "%")
                                    .setParameter("roleKeys5", "%" + split[4] + "%");
                        }
                    }
                }
            }
            return joinPoint.proceed();
        } catch (Exception e) {
            throw e;
        } finally {
            Session session = entityManager.unwrap(Session.class);
            session.disableFilter("orgKeyFilter");
            session.disableFilter("roleKeysFilter");
            session.disableFilter("createByFilter");
        }
    }
}
